#include <iostream>
using namespace std;
namespace YX
{
    template<typename T>
    struct forward_list_node
    {
        forward_list_node<T>* _next;
        T _data;

        forward_list_node(const T& data)
            :_next(nullptr)
            ,_data(data)
        {

        }

    };

    template<class T,class Ref,class Ptr>
    class forward_list_iterator
    {
        typedef forward_list_node<T> node;

        private:
            node* _node;

        public:
            forward_list_iterator(node* n)
                :_node(n)
            {

            }

            // 值拷贝无需自己写
            //forward_list_iterator(const forward_list_iterator<T,Ref,Ptr>& copy)
            //{
            //    _node=copy._node;
            //}

            //forward_list_iterator<T,Ref,Ptr>& operator=(const forward_list_iterator<T,Ref,Ptr>& copy)
            //{
            //    _node=copy._node;
            //}

            forward_list_iterator& operator++()
            {
                _node=_node->_next;

                return *this;
            }

            forward_list_iterator operator++(int)
            {
                forward_list_iterator<T,Ref,Ptr> tmp(*this);

                _node=_node->_next;

                return tmp;
            }

            Ref operator*()
            {
                return _node->_data;
            }

            Ptr operator->()
            {
                return &(operator*());
            }
            
            bool operator!=(const forward_list_iterator<T,Ref,Ptr>& it)
            {
                _node!=it._node;
            }

            bool operator==(const forward_list_iterator<T,Ref,Ptr>& it)
            {
                _node==it._node;
            }
    };

    template<class T>
    class forward_list 
    {   
        typedef forward_list_node<T> node;
        private:
            node* _head;
        public:

            // 迭代器
            typedef forward_list_iterator<T,const T&,const T*> iterator;

            forward_list()
                :_head(new node(T()))
            {

            }
            
            void push_front(const T& data)
            {
                node* newNode=new node(data);

                newNode->_next=_head->_next;

                _head->_next=newNode;
            }

            void pop_front()
            {
                node* del=_head->_next;

                _head->_next=del->_next;
                
                delete del;
            }

            bool empty()
            {
                return _head->_next==nullptr;
            }

            std::size_t size()
            {
                node* curr=_head->_next;

                std::size_t ret=0;

                while(curr!=nullptr)
                {
                    ret++;
                    curr=curr->_next;
                }

                return ret;
            }

            iterator begin()
            {
                return iterator(_head->_next);
            }

            iterator end()
            {
                return iterator(nullptr);
            }

    };
};
